﻿using DiLe.Mes.Model.Cloud.Statistics;
using DiLe.Mes.Model.Common.APP;
using Quartz;

namespace DiLe.Mes.Local.Jobs {
    /// <summary>
    /// 
    /// </summary>
    [DisallowConcurrentExecution]
    public class DeliveryYesterDayJob : IJob {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>

        public async Task Execute(IJobExecutionContext context) {
            await PushEquipmentStatisticsAsync();
        }

        /// <summary>
        /// 设备运行时间统计
        /// </summary>
        /// <returns></returns>
        public async Task PushEquipmentStatisticsAsync() {
            DateTime currentDate = DateTime.Now.AddDays(-1).Date;
            var where = Expressionable.Create<EquipmentOperationEntity>();

            var starTime = currentDate.AddHours(7);
            var endTime = currentDate.AddDays(1).AddHours(9);
            where.And(p => p.CreateTime >= starTime);
            where.And(p => p.CreateTime <= endTime);

            var list = await SqlSugarHelper.MasterDb.Queryable<EquipmentOperationEntity>().Where(where.ToExpression()).ToListAsync();
            if (list.None()) {
                return;
            }
            var dataMap = list.GroupBy(x => x.DeviceNo).Select(x => (x.Key, x.OrderBy(y => y.CreateTime).ToList())).ToList();

            var pushDatas = new List<EquipmentStatisticsEntity>();
            foreach (var item in dataMap) {
                var dcount = item.Item2.Count(x => x.CreateTime <= currentDate.AddHours(19));
                var ncount = item.Item2.Count(x => x.CreateTime >= currentDate.AddHours(21).AddMinutes(-1));
                //日班
                EquipmentStatisticsEntity? dm = null;
                //夜班
                EquipmentStatisticsEntity? nm = null;
                if (dcount > 0 && ncount > 0) {
                    dm = GetDayEquipmentStatistics(item.Key, currentDate, item.Item2, false);
                    nm = GetNightEquipmentStatistics(item.Key, currentDate, item.Item2, false);
                } else if (dcount > 0) {
                    dm = GetDayEquipmentStatistics(item.Key, currentDate, item.Item2, true);
                } else if (ncount > 0) {
                    nm = GetNightEquipmentStatistics(item.Key, currentDate, item.Item2, true);
                }

                if (dm?.ActualWorkingHour > 0) {
                    if (dm.Date == null) {
                        dm.Date = currentDate;
                    }
                    dm.FactoryId = AppHelper.AppSettingInfo.AppId.ToLong();
                    pushDatas.Add(dm);
                }

                if (nm?.ActualWorkingHour > 0) {
                    if (nm.Date == null) {
                        nm.Date = currentDate;
                    }
                    nm.FactoryId = AppHelper.AppSettingInfo.AppId.ToLong();
                    pushDatas.Add(nm);
                }
            }

            HttpClientHelper helper = new();
            var url = AppHelper.GetConfig("AppSetting", "CloudUrl");
            // 发起 Post 请求
            await helper.PostJsonAsync($"{url}/api/init/SynchronousEquipmentStatistics", pushDatas.ToJosn());
        }
        /// <summary>
        /// 日班
        /// </summary>
        /// <returns></returns>
        private static EquipmentStatisticsEntity GetDayEquipmentStatistics(string deviceno, DateTime date, List<EquipmentOperationEntity> list, bool iserror) {
            var dataList = new List<EquipmentStatisticsEntity>();
            var m1 = new EquipmentStatisticsEntity {//日班
                DeviceNo = deviceno,
                Date = date,
                Classes = "8:00~20:00",
                ActualWorkingHour = 0
            };
            DateTime start = date.AddHours(8).AddMinutes(-1);
            DateTime end = date.AddHours(20);
            if (iserror) {
                //7~21 误差60分钟
                start = date.AddHours(7);
                end = date.AddHours(21);
            }
            list = [.. list.Where(x => x.CreateTime > start && x.CreateTime <= end).OrderBy(t => t.CreateTime)];

            for (int i = 0; i < list.Count; i++) {
                var ism = list[i];
                if (i == 0) {
                    m1.EquipmentStartTime = ism.StartTime;
                }
                if (ism.StartTime < date.AddHours(8)) {
                    continue;
                }
                DateTime endtime;
                if (!ism.IsFinish || ism.EndTime == null) {
                    if (i == list.Count - 1) {
                        endtime = date.AddHours(20);
                    } else {
                        var nism = list[i + 1];
                        endtime = nism.StartTime;
                    }
                } else {
                    endtime = ism.EndTime.Value;
                }
                if (ism.EndTime > date.AddHours(20)) {
                    endtime = date.AddHours(20);
                }
                if (m1.EquipmentEndTime == null || m1.EquipmentEndTime < ism.EndTime) {
                    m1.EquipmentEndTime = ism.EndTime;
                }
                TimeSpan? ts = endtime - ism.StartTime;
                m1.ActualWorkingHour += (decimal)(ts?.TotalHours ?? 0);
            }
            if (m1.ActualWorkingHour > 12) {
                m1.ActualWorkingHour = 12;
            }
            return m1;
        }
        /// <summary>
        /// 夜班
        /// </summary>
        /// <returns></returns>
        private static EquipmentStatisticsEntity GetNightEquipmentStatistics(string deviceno, DateTime date, List<EquipmentOperationEntity> list, bool iserror) {
            var dataList = new List<EquipmentStatisticsEntity>();
            var m1 = new EquipmentStatisticsEntity {//日班
                DeviceNo = deviceno,
                Date = date,
                Classes = "20:00~8:00",
                ActualWorkingHour = 0
            };
            DateTime start = date.AddHours(20).AddMinutes(-1);
            DateTime end = date.AddHours(32);
            if (iserror) {
                //19~9 误差60分钟
                start = date.AddHours(19);
                end = date.AddHours(33);
            }
            list = [.. list.Where(x => x.CreateTime >= start && x.CreateTime <= end).OrderBy(t => t.CreateTime)];
            for (int i = 0; i < list.Count; i++) {
                var ism = list[i];
                if (i == 0) {
                    m1.EquipmentStartTime = ism.StartTime;
                }
                if (ism.StartTime < date.AddHours(20)) {
                    continue;
                }
                DateTime endtime;
                if (!ism.IsFinish || ism.EndTime == null) {
                    if (i == list.Count - 1) {
                        endtime = date.AddHours(32);
                    } else {
                        var nism = list[i + 1];
                        endtime = nism.StartTime;
                    }
                } else {
                    endtime = ism.EndTime.Value;
                }
                if (ism.EndTime > date.AddHours(32)) {
                    endtime = date.AddHours(32);
                }
                if (m1.EquipmentEndTime == null || m1.EquipmentEndTime < ism.EndTime) {
                    m1.EquipmentEndTime = ism.EndTime;
                }
                TimeSpan? ts = endtime - ism.StartTime;
                m1.ActualWorkingHour += (decimal)(ts?.TotalHours ?? 0);
            }

            if (m1.ActualWorkingHour > 12) {
                m1.ActualWorkingHour = 12;
            }
            return m1;
        }



    }
}
